package encaps.utils.html;

import encaps.resources.Labels;
import static encaps.utils.html.HTML.*;

public class HTMLTableElement extends HTMLElement {

    private int rowNumber;
    private int columnNumber;
    private HTMLElement[][] cells;
    private HTMLElement[] headers = null;
    private boolean colored;

    /**
     * Constructs new HTMLTable element with given size.
     *
     * @param width number of columns in table.
     * @param height number of rows in table.
     */
    public HTMLTableElement(int rowNumber, int columnNumber, boolean colored) {
        super(TABLE);
        this.rowNumber = rowNumber;
        this.columnNumber = columnNumber;
        cells = new HTMLElement[rowNumber][columnNumber];
        this.colored = colored;
    }

    /**
     * Puts content into given table header
     *
     * @param columnNumber column number (begins with 0).
     * @param content header content.
     */
    public void addHeader(int columnNumber, String content) {
        if (headers == null) {
            headers = new HTMLElement[this.columnNumber];
        }
        headers[columnNumber] = new HTMLElementSequence().addContent(content);
    }

    /**
     * Puts content into given table header
     *
     * @param columnNumber column number (begins with 0).
     * @param content header content.
     */
    public void addHeader(int columnNumber, HTMLElement content) {
        if (headers == null) {
            headers = new HTMLElement[this.columnNumber];
        }
        headers[columnNumber] = content;
    }

    /**
     * Puts text content into given cell.
     *
     * @param row row number of cell (begins with 0).
     * @param column column number of cell (begins with 0).
     * @param content content to add.
     */
    public void addContentToCell(int row, int column, String content) {
        checkIndexes(row, column);

        HTMLElement cell = new HTMLElement(TD);
        cell.addContent(content);
        cells[row][column] = cell;
    }

    /**
     * Puts HTML element into given cell.
     *
     * @param row row number of cell (begins with 0).
     * @param column column number of cell (begins with 0).
     * @param content content to add.
     */
    public void addContentToCell(int row, int column, HTMLElement content) {
        checkIndexes(row, column);
        HTMLElement cell = new HTMLElement(TD);
        cell.addContent(content);
        cells[row][column] = cell;
    }

    /**
     * Returns HTML code representing the constructed object which can be
     * included into a web page.
     *
     * @return a string with the HTML code.
     */
    @Override
    public String toString() {
        if (children != null) {
            children.clear();
        }

        if (headers != null) {
            HTMLElement row = new HTMLElement(TR);
            for (int i = 0; i < headers.length; i++) {
                HTMLElement header = new HTMLElement(TH);
                header.addContent(headers[i]);
                row.addContent(header);
            }
            super.addContent(row);
        }

        boolean odd = true;
        for (int i = 0; i < rowNumber; i++) {
            HTMLElement row = new HTMLElement(TR);
            if (odd && colored) {
                row.addAttribute(CLASS, Styles.ODD_TABLE_ROW);
            }
            odd = !odd;
            for (int j = 0; j < columnNumber; j++) {
                HTMLElement cell = cells[i][j];
                if (cell != null) {
                    row.addContent(cell);
                }
            }
            super.addContent(row);
        }
        return super.toString();
    }

    private void checkIndexes(int row, int column) {
        if (row >= rowNumber || row < 0) {
            throw new TableIndexOutOfBoundsException(Labels.getLabel(Labels.WRONG_TABLE_ROW_MESSAGE) + (rowNumber - 1));
        }
        if (column >= columnNumber || column < 0) {
            throw new TableIndexOutOfBoundsException(Labels.getLabel(Labels.WRONG_TABLE_COLUMN_MESSAGE) + (columnNumber - 1));
        }
    }
}
